/**
 * @description 装饰器
 * @date 2025.5.15
 * @author wz
 * @midify 2025.5.15
 * @editor wz
 */
import { Constructor } from "cc";
import { proxyMgr } from "./ProxyMgr";
import { ProxyBase } from "./ProxyBase";

/** 
 * 定义属性为控制器(属性装饰器)
 */
export const ctrl = (target: any, ctrlKey: string) => {
    const targetName = target.name;
    let ctrlData = proxyMgr.proxyPropertyMetaMap.get(targetName);
    if (!ctrlData) {
        ctrlData = new Map();
        proxyMgr.proxyPropertyMetaMap.set(targetName, ctrlData);
    }

    // 定义私有变量名
    const privateKey = "_" + ctrlKey;

    // 初始化私有变量
    Object.defineProperty(target, privateKey, {
        value: 0,
        writable: true,
        enumerable: false,
        configurable: true,
    });

    // getter 和 setter
    const getter = () => target[privateKey];
    const setter = (newVal: any) => {
        console.log(`Setter triggered for ${ctrlKey}:`, newVal); // 调试日志
        target[privateKey] = newVal;
        target._onCtrl(ctrlKey, newVal);
    };

    // 定义公共属性
    Object.defineProperty(target, ctrlKey, {
        get: getter,
        set: setter,
        enumerable: true,
        configurable: true,
    });
}
/** 
 * 为属性添加控制(属性装饰器)
 */
export const addctrl = (ctrlKey: string, ...ctrlValues: number[]) => {
    return (target: any, propertyKey: string) => {
        const targetName = target.name;
        let ctrlData = proxyMgr.proxyPropertyMetaMap.get(targetName)
        if (!ctrlData) {
            ctrlData = new Map()
            proxyMgr.proxyPropertyMetaMap.set(targetName, ctrlData);
        }

        let ctrl = ctrlData.get(ctrlKey);
        if (!ctrl) {
            ctrl = []
            ctrlData.set(ctrlKey, ctrl);
        }

        const index = ctrl.findIndex(a => a.propertyKey === propertyKey);
        if (index >= 0) {
            ctrl[index] = { propertyKey, ctrlValues };
        } else {
            ctrl.push({ propertyKey, ctrlValues });
        }
    }
}

/**
 * 定义类为代理(类装饰器)
 */
export const proxy = (bundle: string, path: string) => {
    return (proxyCtor: any) => {
        const proxyName = proxyCtor.name;
        const meta = proxyMgr.proxyMetaMap.get(proxyName);
        if (meta?.bundle && meta?.path) {
            console.warn(`proxy------${proxyName}有重复装饰`);
            return;
        }
        proxyMgr.proxyMetaMap.set(proxyName,
            {
                bundle,
                path,
                proxyName,
                ctor: meta?.ctor,
            });
    }
}

/** 
 * 为类绑定一个代理(类装饰器)
 */
export const bind = (proxyClass: Constructor<ProxyBase>) => {
    return (wndCtor: any) => {
        const proxyName = proxyClass.name;
        const meta = proxyMgr.proxyMetaMap.get(proxyName);
        if (meta.ctor) {
            console.warn(`bind------${proxyName}有重复绑定`);
            return;
        }
        proxyMgr.proxyMetaMap.set(proxyName,
            {
                bundle: meta?.bundle,
                path: meta?.path,
                proxyName: meta?.proxyName,
                ctor:wndCtor,
            });
    }
}
